#pragma once

typedef unsigned char  UINT8, BYTE, __u8;
typedef unsigned short UINT16, WORD, __u16;
typedef unsigned int   UINT32, size_t, __u32, gfp_t, dev_t;
typedef unsigned long  ULONG, CPUWORD;

typedef enum {FALSE, TRUE} BOOL;


#define __INLINE__ inline

#define __VOLATILE__ volatile

#define __PACKED__  __attribute__((packed))

#define __FUNCTION__  __func__

// #define PRINT_ARG_FORMAT __attribute__((format (printf, 1, 2)))

#define NULL  ((void *)0)

#define CHAR_ESC '\033'

#define WORD_SIZE              sizeof(CPUWORD)
#define WORD_ALIGN_UP(addr)    (((addr) + WORD_SIZE - 1) & ~(WORD_SIZE - 1))
#define WORD_ALIGN_DOWN(addr)  ((addr) & ~(WORD_SIZE - 1))

#define DWORD_SIZE             (WORD_SIZE << 1) 

// #define ALIGN_UP(len, align) (((len) + ((align) - 1)) & ~((align) - 1))
#define ALIGN_UP(len, align) \
	do { \
		typeof(len) nTemp; \
		if (!(align & (align - 1))) { \
			len = (len + align - 1) & ~(align - 1); \
		} else if (nTemp = len % align) { \
			len += align - nTemp; \
		} \
	} while (0)

#define ARRAY_ELEM_NUM(arr) (sizeof(arr) / sizeof(arr[0]))


#define MemToObj(ptr, type, member) \
	(type *)((char *)ptr - (char *)(&((type *)0)->member))


#define min_t(type, x, y) \
		({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })

#define max_t(type, x, y) \
		({ type __x = (x); type __y = (y); __x > __y ? __x: __y; })

#define min(x, y) ((x) < (y) ? (x) : (y))
#define max(x, y) ((x) > (y) ? (x) : (y))


#define cpu_to_le16(x) (x)
#define le16_to_cpu(x) (x)


#define KB(n) ((n) << 10)
#define MB(n) ((n) << 20)
#define GB(n) ((n) << 30)


typedef enum
{
	GB_OK,
	GB_QUIT,

} GB_STAT;


// fixme: #if debug

#define BUG() \
	do { \
		printf(" BUG @ %s() line %d!\n", __FUNCTION__, __LINE__); \
		while (1); \
	} while(0)


#if 1
#define BUG_IF(x) \
	if (x) \
	{  \
		printf(" BUG @ %s() line %d!\n", __FUNCTION__, __LINE__); \
		while(1); \
	}
#else
#define BUG_IF(x)
#endif


